#include "LED.h"
#include "SOFT_PWM.h"
#include "UserOS\OS_Event.h"

const uint8 TAB_SCENE_LOADING[] = {100,80,60,40,20,1};      //

uint8 CntRunTm=0,RunIdx=0;
uint8 LoopEN=0;
uint8 LedScene=0;

Typedef_LED_FLASH LedFlash_Ctrl;

uint8 CheckAllLed(uint8 duty)
{
    if((PWM_Ctrl.Duty[0] == duty)&&(PWM_Ctrl.Duty[1] == duty) && 
        (PWM_Ctrl.Duty[2] == duty)&&(PWM_Ctrl.Duty[3] == duty) &&
        (PWM_Ctrl.Duty[4] == duty)&&(PWM_Ctrl.Duty[5] == duty))
        {
            return YES;
        }
    else
    {
        return NO;
    }
}

void LedScene_Init(void)
{
    RunIdx = 0;
    CntRunTm = 0;
    // memset(PWM_Ctrl.Duty,0,6);
    // memset(DestPwmDuty,0,6);
}

void LedScene_Loading(void)
{
    CntRunTm++;
    if(CntRunTm >= _SCENE_PERIOD_TIME_)
    {
        uint8 i;

        CntRunTm = 0;

        for(i=0; i<6; i++)
        {
            uint8 idx = RunIdx + i;
            if(idx >= 6)    
                idx -= 6;
        
        #if _SCENE_LOADING_CW_
            DestPwmDuty[5-i] = TAB_SCENE_LOADING[idx];      //
        #else
            DestPwmDuty[i] = TAB_SCENE_LOADING[idx];      //
        #endif
        }

        RunIdx++;
        if(RunIdx >=6)  
        {
            RunIdx = 0;
            if(LoopEN == NO)
            {
                Led_SwitchScene(LED_SCENE_IDLE);
                // if(OS_GetEvent(OS_STATE_LED))
                // {
                //     memset(DestPwmDuty,MAX_PWM_STEP,6);
                // }
                // else
                // {
                //     memset(DestPwmDuty,0,6);
                // }
                OS_SetEvent(OS_EVENT_SCENE_LOADING_END);
            }
        }

        TmPwmChange = 2;
    }
}


uint8 NextDuty;
void LedScene_Breathing(void)
{
    switch(RunIdx)
    {
        case 0:
            if(CheckAllLed(0))
            {
                NextDuty = MAX_PWM_STEP;
            }
            else
            {
                NextDuty = MIN_BREATH_DUTY;
            }
            memset(DestPwmDuty,NextDuty,sizeof(DestPwmDuty));
            TmPwmChange = SPEED_BREATH_TIME;
            RunIdx++;
        break;

        case 1:
            if(CheckAllLed(NextDuty))
            {
                if(NextDuty == MAX_PWM_STEP)
                {
                    NextDuty = MIN_BREATH_DUTY; 
                }
                else
                {
                    NextDuty = MAX_PWM_STEP;
                }
                memset(DestPwmDuty,NextDuty,sizeof(DestPwmDuty));
                RunIdx++;
            }
        break;

        case 2:
            if(CheckAllLed(NextDuty))
            {
                if(LoopEN)
                {
                    RunIdx--;
                }
                else
                {
                    if(NextDuty==MIN_BREATH_DUTY)     
                        memset(DestPwmDuty,0,sizeof(DestPwmDuty));
                    
                    OS_SetEvent(OS_EVENT_SCENE_BREATH_END);
                    RunIdx++;
                }
            }
        break;

        default:
        break;
    }
}

void LedScene_FadeIn(void)
{
    switch(RunIdx)
    {
        case 0:
            memset(DestPwmDuty,MAX_PWM_STEP,sizeof(DestPwmDuty));
            TmPwmChange = SPEED_FADEIN_TIME;
            RunIdx++;
        break;

        case 1:
            if(CheckAllLed(MAX_PWM_STEP))
            {
                OS_SetEvent(OS_EVENT_SCENE_FADEIN_END);
                RunIdx++;
            }
        break;

        default:
        break;
    }

}


void LedScene_FadeOut(void)
{
    switch(RunIdx)
    {
        case 0:
            memset(DestPwmDuty,0,sizeof(DestPwmDuty));
            TmPwmChange = SPEED_FADEOUT_TIME;
            RunIdx++;
        break;

        case 1:
            if(CheckAllLed(0))
            {
                OS_SetEvent(OS_EVENT_SCENE_FADEOUT_END);
                RunIdx++;
            }
        break;

        default:
        break;
    }

}

void LedScene_SetFlash(uint8 sec1_times, uint8 sec2_times, uint8 sec1_on_time, uint8 sec2_on_time, uint8 interval)
{
    LedFlash_Ctrl.LoopSec1 = sec1_times * 2;
    LedFlash_Ctrl.LoopSec2 = sec2_times * 2;
    LedFlash_Ctrl.OnTimeSec1 = sec1_on_time;
    LedFlash_Ctrl.OnTimeSec2 = sec2_on_time;
    LedFlash_Ctrl.Interval = interval;
    TmPwmChange = 0;
}


void LedScene_Flash(void)
{
    if(F_TimeBase10ms)
    {
        F_TimeBase10ms = NO;
        CntRunTm++;
    }

    switch(RunIdx)
    {
        //---- 第一段初始化 ----//
        case 0:
            TmPwmChange = 0;
            if(CheckAllLed(0))              NextDuty = MAX_PWM_STEP;
            else                            NextDuty = 0;
            // if(OS_GetEvent(OS_STATE_LED))      NextDuty = 0;
            // else                               NextDuty = MAX_PWM_STEP;
            memset(DestPwmDuty,NextDuty,6);
            if(LedFlash_Ctrl.LoopSec1)
                LedFlash_Ctrl.LoopSec1--;
            CntRunTm = 0;
            RunIdx++;
        break;

        //---- 第一段闪烁 ----//
        case 1:
            if(CntRunTm >= LedFlash_Ctrl.OnTimeSec1)
            {
                CntRunTm = 0;
                if(NextDuty)    NextDuty = 0;
                else            NextDuty = MAX_PWM_STEP;
                memset(DestPwmDuty,NextDuty,6);
                if(LedFlash_Ctrl.LoopSec1)
                    LedFlash_Ctrl.LoopSec1--;
                if(LedFlash_Ctrl.LoopSec1 == 0)
                {
                    RunIdx++;
                }
            }
        break;

        // ---- 间隔延时 ----//
        case 2:
            if(CntRunTm >= LedFlash_Ctrl.Interval)
            {
                CntRunTm = 0;
                if(NextDuty)    NextDuty = 0;
                else            NextDuty = MAX_PWM_STEP;
                memset(DestPwmDuty,NextDuty,6);
                if(LedFlash_Ctrl.LoopSec2)
                    LedFlash_Ctrl.LoopSec2--;
                
                RunIdx++;
            }
        break;  

        //---- 第二段闪烁 ----//
        case 3:
            if(CntRunTm >= LedFlash_Ctrl.OnTimeSec2)
            {
                CntRunTm = 0;
                if(NextDuty)    NextDuty = 0;
                else            NextDuty = MAX_PWM_STEP;
                memset(DestPwmDuty,NextDuty,6);
                if(LedFlash_Ctrl.LoopSec2)
                    LedFlash_Ctrl.LoopSec2--;
                if(LedFlash_Ctrl.LoopSec2 == 0)
                {
                    RunIdx++;
                }
            }
        break;

        //---- 闪烁结束 ----//
        case 4:
        break;      

        default:
        break;
    }
}


void Led_SwitchScene(uint8 scene)
{
    if(LedScene != scene)
    {
        LedScene = scene;
    }
    OS_SetEvent(OS_EVENT_SCENE_CHANGE);
}

void Led_Main(void)
{
    if(OS_GetEvent(OS_EVENT_SCENE_CHANGE))
    {
        OS_ClrEvent(OS_EVENT_SCENE_CHANGE);
        LedScene_Init();
    }

    switch(LedScene)
    {
        case LED_SCENE_BREATHING:
            LedScene_Breathing();
        break;

        case LED_SCENE_LOADING:
            LedScene_Loading();
        break;

        case LED_SCENE_FADEIN:
            LedScene_FadeIn();
        break;

        case LED_SCENE_FADEOUT:
            LedScene_FadeOut();
        break;

        case LED_SCENE_FLASH:
            LedScene_Flash();
        break;  

        default:
        break;
    }
}
